Product : ISaGRAF V3

Date    : 5-March-1996

File    : WDKcom2.ISDK_COM.dll implementation using a timer.htm

Subject : ISDK_COM.dll implementation using a timer

Keywords: ISDK_COM - postmessage - isdk_com_send - timer

____________________________________________________________________

Below is the source code of a sample ISDK_COM program. It uses a

timer to delay the postmessage call after isdk_com_send is

processed. Don't care about the hard coded frames built in

isdk_com_receive routine. Just focus on the child window / timer

mechanism. You can use the same timer management in your software.

/*****************************************************************

File : ISDK_COM.c

Description : user defined communications

hard coded connection frames

This examples uses a Timer linked to a child window, to post an

"awake" message to the debugger main window.

Only two frames of the ISaGRAF protocols are handled. They are

hard coded in the isdk_com_receive routine. DONT CARE ABOUT THIS.

The aim of this example is to demonstrate how to use a TIMER and

a CHILD window.

*****************************************************************/

#include "windows.h"

#include "memory.h" /* required for memset */

/* exports: child window callback procedure */

long CALLBACK childwndproc (HWND, UINT, WPARAM, LPARAM);

/* YOU ABSOLUTELY NEED TO ADD THE NAME OF THIS PROCEDURE

IN THE LIST OF EXPORTS IN FILE ISDK_COM.DEF */

/* static data / defines */

#define IDT_TIMER 14 /* timer identifier */

#define PERIOD 100 /* timer duration (after SEND) */

static HWND CHWND; /* child window handle */

static HINSTANCE HINST; /* module (dll) code handle */

static WORD TMRID; /* timer identifier */

/* DLL main entry point */

int FAR PASCAL LibMain (HANDLE hModule, WORD wDataSeg,

WORD cbHeapSize, LPSTR lpszCmdLine)

{

HINST = hModule; /* store module handle to create child window*/

return 1;

}

/* DLL ending point */

int FAR PASCAL WEP (int bSystemExit)

{

return(1);

}

/* dont care about this: just used to hard code the answer */

static WORD DBGMSG;

static HWND WNDDBG;

static BYTE SLAVE;

static BYTE REQ;

static BYTE NT;

int FAR PASCAL isdk_com_isdefined (void)

{

return (1);

}

int FAR PASCAL isdk_com_getname (LPSTR buffer)

{

lstrcpy (buffer, "TestCnx");

return (1);

}

int FAR PASCAL isdk_com_setup (HWND hwndParent, LPSTR projectdir)

{

MessageBox (hwndParent,

"No other parameter needed",

"Test Connection",

MB_OK);

return (1);

}

/*

Child window class registration and child window creation must be

achieved in the ISDK_COM_DEFMESSAGE procedure.

*/

int FAR PASCAL isdk_com_defmessage (HWND hwndDebug,

WORD wakeup_message)

{

WNDCLASS pWndClass;

/* store debugger information */

DBGMSG = wakeup_message;

WNDDBG = hwndDebug;

/* register child window class */

memset (&pWndClass, 0, sizeof (pWndClass));

pWndClass.lpfnWndProc = childwndproc;

pWndClass.hInstance = HINST;

pWndClass.hbrBackground = COLOR_WINDOW+1;

pWndClass.lpszClassName = "ISDK_COM_CHILD";

if (!RegisterClass (&pWndClass)) {

MessageBox (DBGMSG, "Cannot register child window class",

"ISDK_COM Error", MB_OK);

return (0);

}

/* create child window - when everything is running, it is better

to remove the "WS_VISIBLE" attribute. It is not worth to destroy

this window, as child windows are automatically destroyed with

their parent window */

CHWND = CreateWindow ("ISDK_COM_CHILD", /* window class name */

"ISDK com", /* no title */

WS_CHILD|WS_BORDER|WS_VISIBLE|WS_CAPTION,

300, 3, 100, 20,

WNDDBG, /* parent window: debugger */

(UINT)-1,

HINST, NULL);

if (CHWND == NULL) {

MessageBox (DBGMSG, "Cannot create child window",

"ISDK_COM Error", MB_OK);

return (0);

}

return (1);

}

int FAR PASCAL isdk_com_open (WORD isagraf_slave, LPSTR projectdir)

{

return (1);

}

/* THIS IS THE CHILD WINDOW CALLBACK PROCEDURE */

long CALLBACK childwndproc (HWND hWnd, UINT message, WPARAM wParam,

LPARAM lParam)

{

PAINTSTRUCT ps;

switch (message) {

case WM_PAINT :

BeginPaint (hWnd, &ps);

EndPaint (hWnd, &ps);

break;

case WM_TIMER :

/* timer event: normally you write the following algorithm:

if (data_is_ready) {

post message to debugger window

kill timer (no more needed)

}

else {

nothing: wait for next timer event

}

*/

if (wParam == IDT_TIMER) {

PostMessage (WNDDBG, DBGMSG, 0, 0L);

KillTimer (CHWND, IDT_TIMER);

TMRID = 0;

}

break;

default :

return (DefWindowProc (hWnd, message, wParam, lParam));

}

return (NULL);

}

 

int FAR PASCAL isdk_com_close (void)

{

/* you dont need to destroy child window

Windows does it for you */

return (1);

}

int FAR PASCAL isdk_com_send (LPBYTE snd_data, WORD snd_size)

{

SLAVE = *snd_data;

NT = snd_data[2];

if (snd_data[1] == 0x41

&& snd_data[5] == 0x0a

&& snd_data[6] == 0x00)

REQ = 1;

else if (snd_data[1] == 0x43 && snd_data[5] == 0x35)

REQ = 2;

else REQ = 0;

if (REQ) {

/* when data is sent, set the timer: the whild window callback

procedure will be awaken with WM_TIMER message */

TMRID = SetTimer (CHWND, IDT_TIMER, PERIOD, NULL);

}

return ((int)REQ);

}

int FAR PASCAL isdk_com_receive (LPWORD errcode, LPWORD rcv_size,

LPBYTE rcv_data)

{

/* isdk_com_receive is called only when data is ready, according to

the following sequence:

1- debugger invokes isdk_com_send:

data is sent

timer is set

2- child window receives wm_timer message

wait for the next message if reveiced data is not ready

3- child window receives wm_timer message when rcv data is ready

kills the timer

post notification message to the debugger

4- debugger invokes isdk_com_receive to get receive data

*/

 

/* the following code just builds a hard coded answer for the two

main frames exchanged when debugger starts */

switch (REQ) {

case 1 : rcv_data[0] = SLAVE;

rcv_data[1] = 0x41;

rcv_data[2] = NT;

rcv_data[3] = 0;

rcv_data[4] = 0x13;

rcv_data[5] = 0x0a;

rcv_data[6] = 0;

rcv_data[7] = 0;

rcv_data[8] = 0;

wsprintf (&(rcv_data[9]), "%c%s%c%s%c",

3, "1.60", 8, "Test_Cnx", 0);

*errcode = 0;

*rcv_size = 24;

break;

case 2 : rcv_data[0] = SLAVE;

rcv_data[1] = 0x43;

rcv_data[2] = NT;

rcv_data[3] = 0;

rcv_data[4] = 9;

rcv_data[5] = 0x35;

rcv_data[6] = 0;

rcv_data[7] = 0;

rcv_data[8] = 0;

rcv_data[9] = 0;

rcv_data[10] = 0;

rcv_data[11] = 0;

rcv_data[12] = 0;

rcv_data[13] = 0;

*errcode = 0;

*rcv_size = 14;

break;

default: *errcode = 1;

*rcv_size = 0;

break;

}

return (1);

}

int FAR PASCAL isdk_com_abort (void)

{

/* kill the timer if it exists */

return (1);

}

____________________________________________________________________

Copyright © 1996-2009 ICS Triplex ISaGRAF Inc. All rights reserved.